package com.qqt.csr.order.service;

import com.alibaba.cola.statemachine.StateMachine;
import com.google.common.collect.Lists;
import com.qqt.csr.common.acl.aics.AICustomerServiceClient;
import com.qqt.csr.common.acl.aics.resp.CsMemberInfoDTO;
import com.qqt.csr.common.exception.StatusCode;
import com.qqt.csr.common.session.SessionContextHolder;
import com.qqt.csr.common.utils.CacheKeyUtil;
import com.qqt.csr.common.utils.RedissonLockUtil;
import com.qqt.csr.common.utils.ServiceAssert;
import com.qqt.csr.order.entity.WorkOrder;
import com.qqt.csr.order.enums.WorkOrderEventEnum;
import com.qqt.csr.order.enums.WorkOrderStatusEnum;
import com.qqt.csr.order.service.statemachine.context.WorkOrderContext;
import com.qqt.csr.order.service.statemachine.rule.WorkOrderStateMachineRule;
import com.qqt.csr.order.utils.OrderNoGenerator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Slf4j
@Service
public class ProcessingWorkOrderEventService {
    @Autowired
    private WorkOrderService workOrderService;
    @Autowired
    private WorkOrderStateMachineRule workOrderStateMachineRule;
    @Autowired
    private OrderNoGenerator orderNoGenerator;
    @Autowired
    private RedissonLockUtil redissonLockUtil;
    @Autowired
    private AICustomerServiceClient customerServiceClient;

    /**
     * 事件处理
     *
     * @param event
     * @param order
     */
    public WorkOrderContext processEvent(WorkOrderEventEnum event, WorkOrder order) {
        return processEvent(event, order, SessionContextHolder.getHeaderInfo().getUserId(), SessionContextHolder.getHeaderInfo().getUserName(), SessionContextHolder.getHeaderInfo().getTenantId());
    }

    /**
     * 事件处理
     *
     * @param event
     * @param order
     */
    public WorkOrderContext processEvent(WorkOrderEventEnum event, WorkOrder order, Long operatorId, String operatorName, String tenantId) {
        log.info("处理工单事件:{},工单id:{},工单名称:{}", event, order.getId(), order.getTitle());
        WorkOrderContext context = new WorkOrderContext();
        context.setToOrder(order);
        context.setTenantId(tenantId);
        context.setOperatorId(operatorId);
        context.setEvent(event);
        context.setOperatorName(operatorName);

        if (WorkOrderEventEnum.CREATED.equals(event) || WorkOrderEventEnum.CREATED_ALLOCATED.equals(event)) {
            String orderCode = orderNoGenerator.generateOrderNo(OrderNoGenerator.WORK_ORDER_PREFIX, operatorId);
            order.init(orderCode, operatorId, tenantId);
            fireEvent(WorkOrderStatusEnum.NONE, event, context);
        } else {
            String lockKey = String.format(CacheKeyUtil.Order.ORDER_EVENT_HANDLE_LOCK_KEY, Optional.ofNullable(order.getId()).orElse(0L));
            redissonLockUtil.distributedLock(() -> {
                WorkOrder fromOrder = workOrderService.getWorkOrder(order.getId(), order.getOrderCode());
                ServiceAssert.notNull(fromOrder, StatusCode.Common.NOT_EXIST.getCode(), "工单不存在！");
                context.setFromOrder(fromOrder);
                fireEvent(WorkOrderStatusEnum.getByStatus(fromOrder.getStatus()), event, context);
            }, lockKey);
        }

        return context;
    }

    /**
     * 执行事件
     *
     * @param fromStatus
     * @param event
     * @param context
     */
    private void fireEvent(WorkOrderStatusEnum fromStatus, WorkOrderEventEnum event, WorkOrderContext context) {
        StateMachine<WorkOrderStatusEnum, WorkOrderEventEnum, WorkOrderContext> stateMachine = workOrderStateMachineRule.getStateMachine();
        ServiceAssert.isTrue(stateMachine.verify(fromStatus, event), StatusCode.Common.ILLEGAL.getCode(), "非法操作！");

        context.setFromStatus(fromStatus);
        WorkOrderStatusEnum toStatus = stateMachine.fireEvent(fromStatus, event, context);
        log.info("工单新状态:{}", toStatus);
    }
}
